package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.core.utils.bean.BeanUtils;
import com.spzx.common.core.web.page.PageDomain;
import com.spzx.common.core.web.page.TableSupport;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.Product;
import com.spzx.product.domain.ProductDetails;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.domain.dto.ProductDTO;
import com.spzx.product.domain.vo.ProductVO;
import com.spzx.product.mapper.ProductSkuMapper;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.ProductDetailsService;
import com.spzx.product.service.ProductService;
import com.spzx.product.mapper.ProductMapper;
import com.spzx.product.service.ProductSkuService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @description 针对表【product(商品)】的数据库操作Service实现
 * @createDate 2024-07-24 18:53:17
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
        implements ProductService {

    @Resource
    ProductDetailsService productDetailsService;
    @Resource
    ProductSkuMapper productSkuMapper;
    @Resource
    SkuStockMapper skuStockMapper;
    @Resource
    ProductSkuService productSkuService;

    @Override
    public Page<ProductVO> listpage(Product product) {
        PageDomain pageDomain = TableSupport.getPageDomain();

        //1、创建分页对象
        Page<ProductVO> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
        //2、自定义mapper实现分页查询
        List<ProductVO> list = baseMapper.selectProductVO(page, product);

        page.setRecords(list);
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveProductDTO(ProductDTO productDTO) {
        //拆分数据存储到对应的表中

        //1、优先保存product数据 并得到他新增后返回的主键值
        Product product = new Product();

        //可以将数据源的属性值拷贝给product对象 相同名称类型的属性值
        BeanUtils.copyProperties(productDTO, product);
        product.setCreateBy(SecurityUtils.getUsername());
        baseMapper.insert(product);

        //获取新增商品的id值
        Long id = product.getId();

        //2、根据主键值保存productDetail数据
        ProductDetails productDetails = new ProductDetails();
        productDetails.setId(id);
        productDetails.setProductId(id);
        //将字符串集合 每两个使用逗号拼接
        productDetails.setImageUrls(StringUtils.join(productDTO.getDetailsImageUrlList(), ","));
        productDetails.setCreateBy(SecurityUtils.getUsername());
        productDetailsService.save(productDetails);

        //3、保存sku数据：每个sku都要关联productId
        List<ProductSku> productSkuList = productDTO.getProductSkuList();
        for (int i = 0; i < productSkuList.size(); i++) {
            ProductSku sku = productSkuList.get(i);
            sku.setProductId(product.getId());
            //生成商品码
            sku.setSkuCode(product.getId() + "_" + i);
            //sku标题： 使用spu标题+sku规格属性值
            sku.setSkuName(product.getName() + " " + sku.getSkuSpec());

            sku.setCreateBy(SecurityUtils.getUsername());
            productSkuMapper.insert(sku);


            //4、每次保存sku时 同时保存他的库存 stock关联skuId
            SkuStock skuStock = new SkuStock();
            skuStock.setSkuId(sku.getId());
            skuStock.setTotalNum(sku.getStockNum());
            skuStock.setLockNum(0);
            skuStock.setAvailableNum(sku.getStockNum());
            skuStock.setSaleNum(0);
            skuStock.setStatus(0);

            skuStockMapper.insert(skuStock);

        }


        return true;
    }

    @Override
    public ProductDTO getProductDTOById(Long id) {
        ProductDTO productDTO = baseMapper.selectProductDTOById(id);
        //将查询到的字符串转为集合
        if (StringUtils.isNotEmpty(productDTO.getImagUrls())) {
            productDTO.setDetailsImageUrlList(Arrays.asList(productDTO.getImagUrls().split(",")));
        }
        return productDTO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateProductDTO(ProductDTO productDTO) {
        //1、先更新product数据
        Product product = new Product();
        //将对象转为json，再将json转为product对象
        BeanUtils.copyProperties(productDTO, product);
        product.setUpdateBy(SecurityUtils.getUsername());
        baseMapper.updateById(product);

        //2、再更新productDetails数据
        String imageUrls = CollectionUtils.isEmpty(productDTO.getDetailsImageUrlList())
                ? null : StringUtils.join(productDTO.getDetailsImageUrlList(), ",");
        //如果存在就更新，不存在就新增
        ProductDetails productDetails = productDetailsService.getOne(Wrappers.lambdaQuery(ProductDetails.class)
                .eq(ProductDetails::getProductId, product.getId()));
        productDetails = productDetails == null ? new ProductDetails() : productDetails;
        productDetails.setImageUrls(imageUrls);
        productDetails.setProductId(product.getId());
        productDetailsService.saveOrUpdate(productDetails);

        //3、再更新sku数据
        productDTO.getProductSkuList().forEach(sku -> {
            sku.setUpdateBy(SecurityUtils.getUsername());
            //重新生成sku名称
            sku.setSkuName(product.getName() + " " + sku.getSkuSpec());
            productSkuMapper.updateById(sku);

            //4、再更新sku库存数据
            Integer stockNum = sku.getStockNum();
            //先查询库存
            SkuStock skuStock = skuStockMapper.selectOne(Wrappers.lambdaQuery(SkuStock.class)
                    .eq(SkuStock::getSkuId, sku.getId())
                    .last("limit 1"));

            skuStock.setAvailableNum(stockNum - skuStock.getLockNum());
            skuStock.setTotalNum(stockNum);
            skuStock.setUpdateBy(SecurityUtils.getUsername());
            skuStockMapper.updateById(skuStock);
        });


        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeBatchSpusById(List<Long> ids){
        //根据id批量删除spu数据
        this.removeBatchByIds(ids);

        //批量删除详情图
        productDetailsService.remove(Wrappers.lambdaQuery(ProductDetails.class)
                .in(ProductDetails::getProductId, ids));

        //根据id批量删除sku数据
        List<Long> skuIds = productSkuMapper.selectList(Wrappers.lambdaQuery(ProductSku.class)
                .in(ProductSku::getProductId, ids)
                .select(ProductSku::getId))
                .stream()
                .map(sku -> sku.getId())
                .collect(Collectors.toList());

        //删除库存需要先查询skuId集合  在删除
        skuStockMapper.delete(Wrappers.lambdaQuery(SkuStock.class)
                .in(SkuStock::getSkuId, skuIds));


        return true;
    }

    @Override
    public boolean updateStatus(Long id, Integer status) {
        //spu
       this.update(Wrappers.lambdaUpdate(Product.class)
                .eq(Product::getId, id)
                .set(Product::getStatus, status)
                .set(Product::getUpdateBy, SecurityUtils.getUsername()));

        //更新sku上下架状态
        productSkuService.update(Wrappers.lambdaUpdate(ProductSku.class)
                .eq(ProductSku::getProductId, id)
                .set(ProductSku::getStatus, status)
                .set(ProductSku::getUpdateBy, SecurityUtils.getUsername()));

        return false;
    }
}




